package com.pi.pro.xcmg.am.common;

import com.pi.common.utils.ByteUtils;
import com.pi.common.utils.TextUtils;
import lombok.extern.slf4j.Slf4j;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayOutputStream;
import java.io.FileWriter;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Properties;

/**
 * AES加密解密工具类
 * 实际生产环境中，密钥应该通过更安全的方式管理（如环境变量、密钥管理服务）
 */
@Slf4j
public class XcmgEncryptionSupport {
    // 密钥长度必须是16、24或32字节
    private static final String SECRET_KEY = System.getenv("LICENSE_ENCRYPT_KEY");

    public static boolean tracing = false;
    
    // AES加密
    public static String encrypt(String data) throws Exception {
        if (SECRET_KEY == null || SECRET_KEY.length() == 0) {
            throw new IllegalArgumentException("加密密钥未配置");
        }
        
        SecretKeySpec keySpec = new SecretKeySpec(
            SECRET_KEY.getBytes(StandardCharsets.UTF_8), 
            "AES"
        );
        
        //Cipher cipher = Cipher.getInstance("AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, keySpec);
        
        byte[] encryptedData = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedData);
    }
    
    // AES解密
    public static String decrypt(String encryptedData) throws Exception {

        traceInfo("//==Encrypt:A01");
        if (SECRET_KEY == null || SECRET_KEY.length() == 0) {
            throw new IllegalArgumentException("加密密钥未配置");
        }
        //traceInfo("//==Encrypt:encode:"+encryptedData);
        //traceInfo("//==Encrypt:key:"+SECRET_KEY);

        traceInfo("//==Encrypt:A02");
        SecretKeySpec keySpec = new SecretKeySpec(
            SECRET_KEY.getBytes(StandardCharsets.UTF_8), 
            "AES"
        );

        traceInfo("//==Encrypt:A03");
        //Cipher cipher = Cipher.getInstance("AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

        traceInfo("//==Encrypt:A04");
        cipher.init(Cipher.DECRYPT_MODE, keySpec);

        traceInfo("//==Encrypt:A05");
        byte[] decodedData = Base64.getDecoder().decode(encryptedData);
        //traceInfo("//==Encrypt:decodedData:"+ ByteUtils.hexStringValue(decodedData, true));

        traceInfo("//==Encrypt:A06");
        byte[] decryptedData = cipher.doFinal(decodedData);

        traceInfo("//==Encrypt:A07");
        return new String(decryptedData, StandardCharsets.UTF_8);
    }

    // DES加密
    public static String desEncrypt(String data) throws Exception {
        System.out.println("KEY:"+SECRET_KEY);
        if (SECRET_KEY == null || SECRET_KEY.length() != 8) { // DES密钥必须8字节
            throw new IllegalArgumentException("DES加密密钥未配置或长度不是8字节");
        }

        // 使用DES算法
        SecretKeySpec keySpec = new SecretKeySpec(
                SECRET_KEY.getBytes(StandardCharsets.UTF_8),
                "DES"
        );

        // 模式：ECB，填充方式：PKCS5Padding（DES常用组合）
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, keySpec);

        byte[] encryptedData = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedData);
    }

    // DES解密
    public static String desDecrypt(String encryptedData) throws Exception {
        traceInfo("//==DEncrypt:A01");
        if (SECRET_KEY == null || SECRET_KEY.length() != 8) {
            throw new IllegalArgumentException("DES加密密钥未配置或长度不是8字节");
        }
        //traceInfo("//==DEncrypt:encode:"+encryptedData);
        //traceInfo("//==DEncrypt:key:"+SECRET_KEY);

        traceInfo("//==DEncrypt:A02");
        SecretKeySpec keySpec = new SecretKeySpec(
                SECRET_KEY.getBytes(StandardCharsets.UTF_8),
                "DES"
        );

        traceInfo("//==DEncrypt:A03");
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");

        traceInfo("//==DEncrypt:A04");
        cipher.init(Cipher.DECRYPT_MODE, keySpec);

        traceInfo("//==DEncrypt:A05");
        byte[] decodedData = Base64.getDecoder().decode(encryptedData);
        //traceInfo("//==Encrypt:decodedData:"+ ByteUtils.hexStringValue(decodedData, true));

        traceInfo("//==DEncrypt:A06");
        byte[] decryptedData = cipher.doFinal(decodedData);

        traceInfo("//==DEncrypt:A07");
        return new String(decryptedData, StandardCharsets.UTF_8);
    }

    public static void license() {
        try {
            // 要加密的授权信息
            //String licenseKey = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456"; // 32位示例密钥
            //String licenseKey = "ABCDEFGHIJKLMNOP"; // 32位示例密钥
            String licenseKey = "M81Xsjwus8vdgysU"; // 16位示例密钥 //server.update.arch.pass
            //licenseKey = "M81Xsjwu"; // 16位示例密钥 //server.update.arch.pass
            String expiryDate = "2025-08-28"; // 过期日期

            // 创建属性文件内容
            Properties props = new Properties();
            props.setProperty("license.key", licenseKey);
            props.setProperty("license.expiryDate", expiryDate);

            // 转换为字符串
            StringBuilder buffer = new StringBuilder();
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            props.store(byteArrayOutputStream, "License Information");
            buffer.append(byteArrayOutputStream.toString());


            // 加密内容
            String encryptedContent = encrypt(buffer.toString());

            // 写入文件
            try{
                //FileWriter writer = new FileWriter("license.enc", StandardCharsets.UTF_8);
                FileWriter writer = new FileWriter("license.enc");
                writer.write(encryptedContent);
                writer.flush();
                traceInfo("文件生成:"+writer);
            }catch(Exception e){
                e.printStackTrace();
            }
            System.out.println("授权文件生成成功: license.enc");
        } catch (Exception e) {
            System.err.println("生成授权文件失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    private static void traceInfo(String text){
        if (text==null){
            return ;
        }
        if (!tracing){
            return;
        }
        log.info(text);
    }

    public static String key(){
        return SECRET_KEY;
    }

}
    